/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ag;

import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;

/**
 *
 * @author T
 */
public class genetica {
    
    int size_individuo;
    int size_poblacion;
    int [] posInicial;
    int []posFinal;
    int []posActual;
    int distancia;
    int distanciaActual;
    double p_seleccion_torneo;
    //int[][] poblacion;
    ArrayList poblacion;
    ArrayList poblacion_temporal;
    ArrayList padres;
    ArrayList mejores;
    public int[][] matriz; //matriz donde se almancena el estado (-1:origen, -2:destino, 0:libre, 1:obstaculo)
    int tamx;
    int tamy;
    
    public genetica (int si){
            size_individuo= si;
            padres = new ArrayList();
            while(this.p_seleccion_torneo<0.5){
            p_seleccion_torneo=this.double_aleatorio();
        }
    }
    
    
    public genetica(int si,int[] pi, int[] pf){
        /**se indica el tama;o del individuo posicion inicial y final del laberinto***/
        size_individuo= si;
        posInicial=pi;
        posActual=posInicial;
        posFinal=pf;
        padres = new ArrayList();
        /*** Se define valor P que servira para 
         * la seleccion de individuo por torneo probalistico
         * este valor debe de estar entre 0.5 y 1.
         */
        poblacion_temporal = new ArrayList(this.size_poblacion);
        while(this.p_seleccion_torneo<0.5){
            p_seleccion_torneo=this.double_aleatorio();
        }
        
        /***************************************/
        definir_distancia();
        
    }
    
    public void definir_distancia(){
    distancia=0;
    /*** Se calcula la diferencia entre la posicion X inicial y la final***/
    distancia=Math.abs(posInicial[0]-posFinal[0]);
    /*** Se calcula la diferencia entre la posicion Y inicial y la final***/
    distancia+=Math.abs(posInicial[1]-posFinal[1]);
    distanciaActual= distancia;
    System.out.println("--*Distancia actual:"+distanciaActual);
    }
    
    public void setMatriz(int[][] mat, int cantx, int canty){
        this.matriz = mat;
        this.tamx = cantx;
        this.tamy = canty;
    }
    
    /******* Metodos solo para probar ************/
    
    public void show_poblacion_temporal(){
        System.out.println("poblacion temporal:");
        System.out.println(this.poblacion_temporal.size());
    }
    
    public void setFitnessRandom(){
    cromosoma individuo;
    poblacion_temporal = new ArrayList(this.size_poblacion);
        Iterator it = poblacion.iterator();
        while (it.hasNext()) {             
          individuo = (cromosoma) it.next();          
          individuo.setFitness(this.numero_aleatorio(100));
          poblacion_temporal.add(individuo);
        } 
        poblacion = poblacion_temporal;
    }
    
    public void showpadres(){
        System.out.println("/****** padres***********/");
        cromosoma individuo;
        Iterator it = padres.iterator();
        while (it.hasNext()) {             
          individuo = (cromosoma) it.next();          
          this.mostrar_individuo(individuo);
        }
    }
    public void mostrar_individuo(cromosoma c){
        //System.out.println("/*otro cromosoma*/");
        System.out.println("Solucion:");
        for (int i=0;i<this.size_individuo;i++){
            System.out.print(c.getAlelos()[i]);            
        }
        System.out.print(" Fitness: "+c.getFitness());
        System.out.println();
        //System.out.println("/****************/");
    }
        public void mostrarSolucion(cromosoma c){
        //System.out.println("/*otro cromosoma*/");
        System.out.println("Solucion:>>");
        for (int i=0;i<c.getTamSolucion();i++){
            System.out.print(c.getAlelos()[i]);            
        }
        System.out.print(" Fitness:: "+c.getFitness());
        System.out.println();
        //System.out.println("/****************/");
    }
    
/****************************************************************/    
    public void mover_posicion_actual(int x,int y){
        
    }
    
    public void crear_poblacion_inicial(int tam_po){
        /*** se indica el tama;o de la poblacion****/
        size_poblacion=tam_po;
        //poblacion = new int[size_poblacion][size_individuo];
        poblacion = new ArrayList(size_poblacion);
        /******* se llena la matriz de poblacion con numeros aleatorios *****/       
        Random rnum = new Random();                
        for (int num_individuo=0;num_individuo<size_poblacion;num_individuo++){
            int[] genotipo = new int[size_individuo];            
            for(int alelo=0;alelo<size_individuo;alelo++){
                genotipo[alelo]=  rnum.nextInt(8);;
            }
            poblacion.add(new cromosoma(genotipo));            
        }
        
    }
    
        public void nuevaGeneracion(){
        cromosoma individuo;
        mejores = new ArrayList();
        for(int i=0; i<poblacion.size(); i++){
            individuo = (cromosoma)poblacion.get(i);
            if(individuo.getFitness()>0){
                mejores.add(individuo);
            }
        }
        Random rnum = new Random();                
        for (int j=mejores.size();j<size_poblacion;j++){
            int[] genotipo = new int[size_individuo];            
            for(int alelo=0;alelo<size_individuo;alelo++){
                genotipo[alelo]=  rnum.nextInt(8);;
            }
            mejores.add(new cromosoma(genotipo));            
        }
        poblacion = mejores;
    }
    
    public void evaluar_poblacion(){
        cromosoma individuo;
        Iterator it = poblacion.iterator();
        while (it.hasNext()) {             
          individuo = (cromosoma) it.next();          
          mostrar_individuo(individuo);
        } 
    }
    
    
    
    public int numero_aleatorio(int max){
        int num=-1;
        Random rnum = new Random();
        num= rnum.nextInt(max);
        return num;
    }
    
    public double double_aleatorio(){
        double num=-1;
        Random rnum = new Random();
        num= rnum.nextDouble();
        return num;
    }
    
    public void seleccion (int tipo){
        /*** Numero de selecciones sera el 90% de la poblacion 
         */
        double ns =  0.90 * this.size_poblacion;
        int num_selecciones = (int) ns;
        System.out.println(num_selecciones);
        for(int i=0;i<num_selecciones;i++){
            switch(tipo){
                case 0:{ this.seleccion_ruleta();
                        break;}
                case 1:{ this.seleccion_torneo_deterministico();
                        break;}
                case 2: { this.seleccion_torneo_probabilistico();
                            break;}
            }
        }
    }
    
    public void cruce_padres(int tipo){
        switch(tipo){
                case 0:{ this.cruce_un_punto();
                        break;}
                case 1:{ this.cruce_dos_puntos();
                        break;}
                case 2: { this.cruce_uniforme();
                            break;}
            }
    }
    
/*************************** Tipos de Seleccion****************************/    
    
    public void seleccion_torneo_deterministico(){
        cromosoma individuo1=null;
        cromosoma individuo2=null;
        int pos1=this.numero_aleatorio(this.size_poblacion);
        int pos2=pos1;
        while (pos2==pos1){
        pos2=this.numero_aleatorio(this.size_poblacion);
        }
        individuo1 = (cromosoma) poblacion.get(pos1);
        individuo2 = (cromosoma) poblacion.get(pos2);        
        System.out.print("I1: ");this.mostrar_individuo(individuo1);
        System.out.print("I2: ");this.mostrar_individuo(individuo2);
        System.out.print("Ganador: ");
        if (individuo1.getFitness()>individuo2.getFitness()){
            padres.add(individuo1);
            this.mostrar_individuo(individuo1);
        }else if(individuo2.getFitness()>individuo1.getFitness()){
            padres.add(individuo2);            
            this.mostrar_individuo(individuo2);
        }else{
            padres.add(individuo1);            
            this.mostrar_individuo(individuo1);
        }
        System.out.println();
    }
    
    public void seleccion_torneo_probabilistico(){
        double val_probabilistico=this.double_aleatorio();
        cromosoma individuo1;
        cromosoma individuo2;
        int pos1=this.numero_aleatorio(this.size_poblacion);
        int pos2=pos1;
        while (pos2==pos1){
        pos2=this.numero_aleatorio(this.size_poblacion);
        }
        System.out.println("val_probabilistico:: "+val_probabilistico);
        System.out.println("p_seleccion_torneo:: "+p_seleccion_torneo);
        individuo1 = (cromosoma) poblacion.get(pos1);
        individuo2 = (cromosoma) poblacion.get(pos2);
         System.out.print("I1: ");this.mostrar_individuo(individuo1);
        System.out.print("I2: ");this.mostrar_individuo(individuo2);
        System.out.print("Ganador: ");
        if (val_probabilistico>this.p_seleccion_torneo){
            padres.add(individuo1);
            this.mostrar_individuo(individuo1);
        }else{
            padres.add(individuo2);
            this.mostrar_individuo(individuo2);
        }
    }
    
    public void seleccion_ruleta(){
       ArrayList temp_ruleta = new ArrayList();
        int fitness_total=0;
        double fitness_promedio=0;
        cromosoma individuo;
        Iterator it = poblacion.iterator();
        /**********Se suma el fitness de cada individuo para sacar el fitness total******/
        while (it.hasNext()) {             
          individuo = (cromosoma) it.next();          
          fitness_total+=individuo.getFitness();
        }
        System.out.println("Fitness total: "+fitness_total);
        individuo=null;
        //fitness_promedio=fitness_promedio/this.size_poblacion;        
        /********* Se saca la porcion de probabilidad que tiene cada individuo segun su fitness*********/
        Iterator it2 = poblacion.iterator();
        while (it2.hasNext()) {             
          individuo = (cromosoma) it2.next();  
          int fitness_in = individuo.getFitness();        
          double prob = ((double) fitness_in/ (double)fitness_total);          
          individuo.setProporcionProbabilidad(prob);          
          temp_ruleta.add(individuo);
      //    this.mostrar_individuo(individuo);
      //    System.out.println("probabilidad: "+individuo.proporcion_probabilidad);
        }        
        poblacion = temp_ruleta;
        /*********** Se genera un valor random para sabe que porcentaje de la ruleta se tomara************/
        double valor_ruleta= this.double_aleatorio();
        double probabilidad_sumada=0;
        /****** Se selecciona individuo para realizar cruces*********************/
        individuo=null;
        Iterator it3 = poblacion.iterator();        
        System.out.println("valor de ruleta: "+valor_ruleta);        
        int index=0;
        while (probabilidad_sumada<valor_ruleta){            
            if (it3.hasNext()){
                individuo= (cromosoma) it3.next();
                index++;
                probabilidad_sumada+=individuo.getProporcionProbabilidad();
            }
        }
        System.out.print("individuo seleccionado:");
        this.mostrar_individuo(individuo);        
        poblacion.remove(index-1);
        poblacion.add(individuo);
        padres.add(individuo);
    }
    
/********************* Tipos de Cruce ***************************************/  
    
    public void setTipoCruce(int tipo){
        switch(tipo){
            case 0: this.cruce_un_punto();
                break;
            case 1: this.cruce_dos_puntos();
                break;
            case 2: this.cruce_uniforme();
                break;
        }
    }
    
    public void cruce_un_punto(){
    //this.poblacion_temporal.clear();
    cromosoma padre1;
    cromosoma padre2;    
    int tam_padre1;
    int tam_padre2;
    double cruce=0;
    int pos_cruce=0;
    Iterator it = padres.iterator();
    System.out.println("Numero de Padres: "+padres.size());    
    while (it.hasNext()){
        padre1 = (cromosoma) it.next();
        if(it.hasNext()){
            padre2 = (cromosoma) it.next();
            tam_padre1 = padre1.getAlelos().length;
        tam_padre2 = padre2.getAlelos().length;
        
        if (tam_padre1<tam_padre2){
            cruce= (double) (tam_padre1/2);
        }else if(tam_padre2<tam_padre2){
            cruce= (double) (tam_padre2/2);
        }else {
            cruce= (double) ((tam_padre1)/2);
        }
       
        pos_cruce= (int) cruce;
        int[] alelos= new int[this.size_individuo];
        int[] alelos2= new int[this.size_individuo];
        /*
        for (int i=0;i<pos_cruce;i++){
            alelos[i]=padre1.getAlelos()[i];
        }
        for (int j=pos_cruce;j<this.size_individuo;j++){
            alelos[j]=padre2.getAlelos()[j];
        }
        */
        /** CRUCE*************/
        System.out.println("Posicion cruce: "+pos_cruce);
        
        /************** hijo 1***********************************************/
        this.mostrar_individuo(padre1);
        this.mostrar_individuo(padre2);
        System.arraycopy(padre1.getAlelos(), 0, alelos,0 , pos_cruce);
        System.arraycopy(padre2.getAlelos(), pos_cruce, alelos, pos_cruce, padre2.getAlelos().length-(pos_cruce));
        System.out.print("Hijo 1: ");
        cromosoma hijo1 = new cromosoma(alelos);
        this.mostrar_individuo(hijo1);
        this.poblacion_temporal.add(hijo1);
        /************* hijo 2***************************************************/
        System.arraycopy(padre2.getAlelos(), 0, alelos2,0 , pos_cruce);
        System.arraycopy(padre1.getAlelos(), pos_cruce, alelos2, pos_cruce, padre1.getAlelos().length-(pos_cruce));
        System.out.print("Hijo 2: ");
        cromosoma hijo2 = new cromosoma(alelos2);
        this.mostrar_individuo(hijo2);
        this.poblacion_temporal.add(hijo2);
        }
        
    }
    
    }
    
    public void cruce_dos_puntos(){
    cromosoma padre1;
    cromosoma padre2;    
    int tam_padre1;
    int tam_padre2;
    double cruce=0;
    int pos_cruce=0;
    int pos_cruce2=0;
    Iterator it = padres.iterator();
    System.out.println("Numero de Padres: "+padres.size());    
    while (it.hasNext()){
        padre1 = (cromosoma) it.next();
        if (it.hasNext()){
            padre2 = (cromosoma) it.next();
            tam_padre1 = padre1.getAlelos().length;
        tam_padre2 = padre2.getAlelos().length;
        
        if (tam_padre1<tam_padre2){
            cruce= (double) (tam_padre1/3);
        }else if(tam_padre2<tam_padre2){
            cruce= (double) (tam_padre2/3);
        }else {
            cruce= (double) ((tam_padre1)/3);
        }
       
        pos_cruce= (int) cruce;
        pos_cruce2= pos_cruce + (int) cruce;
        int[] alelos= new int[this.size_individuo];
        int[] alelos2= new int[this.size_individuo];
        /*
        for (int i=0;i<pos_cruce;i++){
            alelos[i]=padre1.getAlelos()[i];
        }
        for (int j=pos_cruce;j<this.size_individuo;j++){
            alelos[j]=padre2.getAlelos()[j];
        }
        */
        /** CRUCE*************/
        System.out.println("Posicion cruce: "+pos_cruce);
        
        /************** hijo 1***********************************************/
        this.mostrar_individuo(padre1);
        this.mostrar_individuo(padre2);
        System.arraycopy(padre1.getAlelos(), 0, alelos,0 , pos_cruce);
        System.arraycopy(padre2.getAlelos(), pos_cruce, alelos, pos_cruce, pos_cruce2);
        System.arraycopy(padre1.getAlelos(), pos_cruce2, alelos, pos_cruce2, padre1.getAlelos().length-(pos_cruce2));
        System.out.print("Hijo 1: ");
        cromosoma hijo1 = new cromosoma(alelos);
        this.mostrar_individuo(hijo1);
        this.poblacion_temporal.add(hijo1);
        /************* hijo 2***************************************************/
        System.arraycopy(padre2.getAlelos(), 0, alelos2,0 , pos_cruce);
        System.arraycopy(padre1.getAlelos(), pos_cruce, alelos2, pos_cruce, pos_cruce2);
        System.arraycopy(padre2.getAlelos(), pos_cruce2, alelos2, pos_cruce2, padre2.getAlelos().length-(pos_cruce2));
        System.out.print("Hijo 2: ");
        cromosoma hijo2 = new cromosoma(alelos2);
        this.mostrar_individuo(hijo2);
        this.poblacion_temporal.add(hijo2);
        }
        
    }
    }
    
    public void cruce_uniforme(){
    /************* generar mascara**********/
        this.poblacion_temporal.clear();
        int[] mascara = new int[this.size_individuo];
        System.out.print("mascara: ");
        for(int i=0;i<this.size_individuo;i++){
            mascara[i] = this.numero_aleatorio(2);
            System.out.print(mascara[i]);
        }
        
        cromosoma padre1;
        cromosoma padre2;    
        int tam_padre1;
        int tam_padre2;
        Iterator it = padres.iterator();
        System.out.println("Numero de Padres: "+padres.size());    
        int[] alelos= new int[this.size_individuo];
        int[] alelos2= new int[this.size_individuo];
        
        while (it.hasNext()){
            padre1 = (cromosoma) it.next();
            if (it.hasNext()){
                padre2 = (cromosoma) it.next();
                this.mostrar_individuo(padre1);
                this.mostrar_individuo(padre2);
                /********* Cruce ***********************/
                for (int j=0;j<this.size_individuo;j++){
                    switch(mascara[j]){
                        case 0:{
                                /********** hijo 1************/
                                alelos[j]=padre1.getAlelos()[j];
                                /********** hijo 2************/
                                alelos2[j]=padre2.getAlelos()[j];
                                break;}
                          case 1:{
                                /********** hijo 1************/
                                alelos[j]=padre2.getAlelos()[j];
                                /********** hijo 2************/
                                alelos2[j]=padre1.getAlelos()[j];                        
                                    break;}
                    }
                }
                /************ Creamos el hijo1**********************/
                System.out.print("Hijo 1: ");
                cromosoma hijo1 = new cromosoma(alelos);
                this.mostrar_individuo(hijo1);
                this.poblacion_temporal.add(hijo1);  
                /************ Creamos el hijo2**********************/        
                System.out.print("Hijo 2: ");
                cromosoma hijo2 = new cromosoma(alelos2);
                this.mostrar_individuo(hijo2);
                this.poblacion_temporal.add(hijo2);
                }
            
        
        }
    
    }
    
/**************** Mutacion******************************/
    public void mutacion_individuos(){
        /**verificamos cuantos individuos faltan en la 
         poblacion temporal para llegar al numero de individuos         
         **/ 
        int num_faltantes= this.size_poblacion-this.poblacion_temporal.size();
        int num_mutaciones = this.numero_aleatorio(num_faltantes+1);
        for (int i=0;i<num_mutaciones;i++){
            /**** obtenemos uno de los hijos que han sido reproducidos para mutuarlo***/
            cromosoma hijo_mutar = (cromosoma) this.poblacion_temporal.get(this.numero_aleatorio(this.poblacion_temporal.size()));
            /*** obtenemos un valor random para el nuevo alelo y la posicion donde se agregara el nuevo valor****/
            int alelo_mutado = this.numero_aleatorio(8);
            int index_alelo_mutar = this.numero_aleatorio(this.size_individuo);
            /**** obtenemos los alelos del hijo a mutar y colocamos el nuevo valor en la posicion obtenida aleatoriamente****/
            int[] nuevo_adn = hijo_mutar.getAlelos();
            nuevo_adn[index_alelo_mutar] = alelo_mutado;
            /********* colocamos los alelos mutados en el hijo a mutar y lo agregamos a la poblacion **********/
            hijo_mutar.setAlelos(nuevo_adn);
            this.poblacion_temporal.add(hijo_mutar);
        }
    }
    
/********************* Reemplazo**************/
    public void reemplazo_poblacion(){
        /**verificamos cuantos individuos faltan en la 
         poblacion temporal para llegar al numero de individuos         
         **/ 
        int num_faltantes= this.size_poblacion-this.poblacion_temporal.size();
        for (int i=0;i<num_faltantes;i++){
            /**** Para llegar al numero de poblacion que se necesita tomamos el crosoma de uno de los padres
             * y lo agregamos a la nueva generacion
             */
            cromosoma nuevo = (cromosoma) this.padres.get(this.numero_aleatorio(this.padres.size()));
            this.poblacion_temporal.add(nuevo);
        }
        /******** ahora hacemos de la poblacion temporal la siguiente generacion por lo que pasamos la
         * poblacion temporal a la poblacion 
         */
        this.poblacion.clear();
        this.poblacion = this.poblacion_temporal;
    }
    
    public void evaluarPoblacion(){
        cromosoma individuo;
        Iterator it = poblacion.iterator();
        while (it.hasNext()) {             
          individuo = (cromosoma) it.next();          
          fitnessFunction(individuo);
        }
    }
    

    
   
    /*********** funcion fitness ******************/
    public int fitnessFunction(cromosoma c){
        int vfitness = 0;
        //sumar valores de acuerdo a las rutas, evaluando cada individuo
        //se tiene la matriz[][], se busca la ruta del individuo y se evalua que
        //en la matriz[x][y] (x,y) es cada posicion de la "posible ruta" 
        //si matriz[x][y]==0 se suma 100 puntos
        //si matriz[x][y]==1 no se suma -es obstaculo-
        //si matriz[x][y]==-1 y (x,y) era alelo[0] se suma 100 -coincide el origen- e igual para el destino
        
        int[] posSig = new int[2];
        int x, y;
        posActual = posInicial;
        for (int i = 0; i < c.getAlelos().length; i++) {
            posSig = evaluarPosicion(c.getAlelos()[i], posActual);
            posActual = posSig;
            x = posSig[0];
            y = posSig[1];
            if ((x < 0) || (y < 0)) { //dirige hacia fuera del grid
                c.setSolucion(false);
                c.fitness = 0;
                i = c.getAlelos().length; //no es solucion, terminar el ciclo
            } 
            else if ((x >= tamx) || (y >= tamy)) { //dirige hacia fuera del grid
                c.fitness = 0;
                c.setSolucion(false);
                i = c.getAlelos().length;
            }
            else if ((x == posFinal[0]) && (y == posFinal[1])) { //llega al final
                c.fitness = c.fitness + (this.size_individuo - i)* (this.size_individuo - i); //fitness = pasos correctos * no.saltos
                c.setSolucion(true);
                c.setTamSolucion(i);
                i = c.getAlelos().length; //este cromosoma si es solucion
            }
            else {
                switch (matriz[x][y]) {
                    case 0: //esta libre
                        c.fitness += 1;
                        //c.setTamSolucion(i);
                        break;
                    case 1: //tiene obstaculo
                        c.setSolucion(false);
                        i = c.getAlelos().length; //este cromosoma no es solucion
                        c.fitness = 0;
                        break;
                    case -2: //es el destino
                        c.fitness = c.fitness + (this.size_individuo - i)* (this.size_individuo - i); //fitness = pasos correctos * no.saltos
                        c.setSolucion(true);
                        c.setTamSolucion(i);
                        i = c.getAlelos().length; //este cromosoma si es solucion
                        break;
                }
            }

        }
        
        return vfitness;
    }
    
    public int[] evaluarPosicion(int dir, int posA[]){ //devuelve la posicion siguiente con base a la direccion
        int sig[] = new int[2];
        
        switch (dir) {
            case 0: //NORTE
                sig[0] = posA[0]-1;
                sig[1] = posA[1];
                break;
            case 1: //NE
                sig[0] = posA[0]-1;
                sig[1] = posA[1]+1;
                break;
            case 2: //ESTE
                sig[0] = posA[0];
                sig[1] = posA[1]+1;
                break;
            case 3: //SE
                sig[0] = posA[0]+1;
                sig[1] = posA[1]+1;
                break;
            case 4: //SUR
                sig[0] = posA[0]+1;
                sig[1] = posA[1];
                break;
            case 5: //SO
                sig[0] = posA[0]+1;
                sig[1] = posA[1]-1;
                break;
            case 6: //OESTE
                sig[0] = posA[0];
                sig[1] = posA[1]-1;
                break;
            case 7: //NO
                sig[0] = posA[0]-1;
                sig[1] = posA[1]-1;
                break;            
        }
        
        return sig;
    }
    
    public cromosoma getSolucion(){
        cromosoma individuo;
        boolean asignado = false;        
        cromosoma solucion = new cromosoma();
        int corto;
        for(int i=0; i<poblacion.size(); i++){
            individuo = (cromosoma)poblacion.get(i);
            if(individuo.isSolucion()){
                //fitness = individuo.getFitness();
                //if(fitness > solucion.getFitness())solucion = individuo;
                corto = individuo.getTamSolucion();
                if(!asignado){
                    solucion = individuo;
                    asignado = true;
                }
                else if(corto < solucion.getTamSolucion())solucion = individuo;
            }
        }        
        
        return solucion;
    }
    
    public int[][] getRuta(cromosoma c){
        System.out.println("origen:"+posInicial[0]+","+posInicial[1]);
        System.out.println("destino:"+posFinal[0]+","+posFinal[1]);
        String str = "";
        int[] posSig = new int[2];
        int[][] ruta = new int[c.getTamSolucion()][2];
        posActual = posInicial;
        for(int i=0; i< c.getTamSolucion(); i++){            
            posSig = evaluarPosicion(c.getAlelos()[i], posActual);
            str += "->["+posSig[0]+ ","+posSig[1]+"]";
            posActual = posSig;    
            ruta[i][0] = posActual[0];
            ruta[i][1] = posActual[1];
        }
        System.out.println(str);
        return ruta;
    }
    
    public String getMasLargo(){
        StringBuilder str = new StringBuilder();
        boolean asignado = false;
        cromosoma individuo;
        cromosoma solucion = new cromosoma();// = (cromosoma)poblacion.get(0); //se asigna por default
        int largo;
        for(int i=0; i<poblacion.size(); i++){
            individuo = (cromosoma)poblacion.get(i);
            if(individuo.isSolucion()){
                largo = individuo.getTamSolucion(); 
                if(!asignado){
                    solucion = individuo;
                    asignado = true;
                }
                else if(largo > solucion.getTamSolucion())solucion = individuo;
            }
        }        
        for(int i=0; i<solucion.getTamSolucion();i++)str.append(solucion.getAlelos()[i]);
        return str.toString();
    }
    
    public String getMasCorto() {
        StringBuilder str = new StringBuilder();
        boolean asignado = false;
        cromosoma individuo;
        cromosoma solucion = new cromosoma();
        int corto;
        for (int i = 0; i < poblacion.size(); i++) {
            individuo = (cromosoma) poblacion.get(i);
            if(individuo.isSolucion()){
                corto = individuo.getTamSolucion(); 
                if(!asignado){
                    solucion = individuo;
                    asignado = true;
                }
                else if(corto < solucion.getTamSolucion())solucion = individuo;
            }
        }
        for(int i=0; i<solucion.getTamSolucion();i++)str.append(solucion.getAlelos()[i]);
        return str.toString();
    }
    
    public void guardarLog(String largo, String corto, String convergencia, String tiempo, String generaciones) {
        String texto = "";
        StringBuilder str = new StringBuilder();
        cromosoma individuo;
        for (int i = 0; i < this.size_poblacion; i++) {
            // grabar los evaluados y el valor de aptitud
            individuo = (cromosoma) poblacion.get(i);
            for (int j = 0; j < this.size_individuo; j++) {
                str.append(individuo.getAlelos()[j]);
            }
            texto += "[" + i + "] Individuo evaluado:" + str.toString() + " [valor aptitud: " + individuo.getFitness() + "]\n";
            str.delete(0, str.length());
        }
        texto += "\nRESULTADOS DE LA EJECUCION:";
        texto += "\n[Individuo mas largo]:"+largo;
        texto += "\n[Individuo mas corto]:"+corto;
        texto += "\n[Convergencia]:"+convergencia;
        texto += "\n[Tiempo]:"+tiempo;
        texto += "\n[Generaciones]:"+generaciones;
        try {
            PrintWriter output = new PrintWriter(new FileWriter("LOG.txt"));
            output.println(texto);
            output.close();
        } catch (Exception e) {
        }
    }
    
    
}
